package com.simons.common.utils.file.bigFile;

import java.io.File;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.simons.common.exception.CommonErrorType;
import com.simons.common.exception.CommonException;

import lombok.extern.log4j.Log4j2;

/**
 * 大文件上传的工具类
 * 
 * @Description:TODO
 * 
 * @author:JSM
 * 
 * @time:2017年12月26日 下午4:36:50
 */
@SuppressWarnings("unchecked")
@Log4j2
public class BigFileUpLoadUtil {
	
	private static final int maxSize = 1 * 1024 * 1024 * 1024; 

	/**
	 * 大文件上传到服务器本地的方法
	 * 
	 * @param request
	 * @param fileUpLaodPath
	 *            文件需要上传到达的地方
	 * @param fileName
	 *            文件的名字
	 * @param tempFilePath
	 *            临时文件存放地址
	 * @param cacheFileSize
	 *            内存文件阈值
	 * @throws CommonException
	 * @throws FileUploadException
	 */
	public static void upLoadFileLocal(HttpServletRequest request, String fileUpLaodPath, String fileName,
			String tempFilePath, int cacheFileSize) throws Exception {
		upLoadFileLocal(request, fileUpLaodPath, fileName, tempFilePath, maxSize);
	}

	/**
	 * 大文件上传到服务器本地的方法
	 * @param request
	 * @param fileUpLaodPath
	 *            上传路径
	 * @param fileName
	 *            文件名
	 * @param tempFilePath
	 *            缓存文件路径
	 * @param cacheFileSize
	 *            缓存文件单个大小
	 * @param sizeMax
	 *            允许的文件最大限制
	 * @throws Exception
	 */
	public static void upLoadFileLocal(HttpServletRequest request, String fileUpLaodPath, String fileName,
			String tempFilePath, int cacheFileSize, int sizeMax) throws Exception {
		// 上传路径
		File file = new File(fileUpLaodPath);
		// 临时文件路径
		File tempFile = new File(tempFilePath);
		if (!file.exists()) {
			file.mkdir();
		}

		if (!tempFile.exists()) {
			tempFile.mkdir();
		}
		// 判断 request 是一个文件上传的 request
		// 通过 ServletFileUpload 类的静态方法 isMultipartContent 来判断
		if (ServletFileUpload.isMultipartContent(request)) {
			// 用 DiskFileItemFactory 创建新的 file items （只是临时的）
			// DiskFileItemFactory 创建FileItem 实例，并保存其内容在内存或者硬盘中
			// 通过一个阀值来决定这个 FileItem 实例是存放在内存或者硬盘中
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 设置阀值大小
			// 不设置的话，默认10k
			// 超过这个阀值，FileItem将直接写入到磁盘
			factory.setSizeThreshold(cacheFileSize);
			// 设置临时文件夹
			// 不设置，默认为系统默认Temp文件路径，调用 System.getProperty("java.io.tmpdir") 获取
			// 超过阀值的 FileItem 实例将存放在这个目录中
			factory.setRepository(tempFile);
			// 构造servletFileUpload 的实例，该实例提供工厂模式创建FileItem的DiskFileItemFactory实例
			ServletFileUpload fileUpload = new ServletFileUpload(factory);
			// 设置一个完整的请求允许的最大大小(注意是完整请求，包括非file类型的表单,比如Text类型)
			fileUpload.setSizeMax(sizeMax);
			// 设置所允许的最大的单个上传文件大小(对应一个FileItem对象)
			// fileUpload.setFileSizeMax(10*1024*1024);

			// 每一个FileItem 对应一个 request 请求中from表单中的 input 元素
			// 解析 request 请求，将request中提交的值存入List数组
			List<FileItem> items = fileUpload.parseRequest(request);

			for (FileItem item : items) {
				try {
					// 是不是一个文件上传组件
					if (!item.isFormField()) {
						log.info("name:" + fileName);
						log.info("length:" + item.getSize());
						item.write(new File(fileUpLaodPath + "/" + fileName));
					} else {
						String desc = item.getString("UTF-8");
						log.info("文件描述：" + desc);
					}
				} catch (Exception e) {
					log.error("文件上传出错", e);
				}
				// 删除旧的缓存文件
				item.delete();
			}
		} else {
			throw new CommonException(CommonErrorType.COMMON_ERROR, ":请设置form表单的enctype属性");
		}
	}
}
